package com.cndw.kungfu.model.player;

import java.util.Collection;
import java.util.List;
import java.util.Map;

import com.cndw.commons.util.BlankUtils;
import com.cndw.kungfu.config.Constants;
import com.cndw.kungfu.config.ConstantsIntKey;
import com.cndw.kungfu.config.ConstantsModel;
import com.cndw.kungfu.config.EquipType;
import com.cndw.kungfu.domain.Goods;
import com.cndw.kungfu.domain.Player;
import com.cndw.kungfu.domain.Skill;
import com.cndw.kungfu.domain.SkillMode;
import com.cndw.kungfu.domain.Title;
import com.cndw.kungfu.domain.UnionSkillConfig;
import com.cndw.kungfu.domain.Vocation;
import com.cndw.kungfu.ext.NumberProcesser;
import com.cndw.kungfu.model.Context;
import com.cndw.kungfu.model.disciple.PlayerMartial;
import com.cndw.kungfu.model.disciple.domain.Disciple;
import com.cndw.kungfu.model.disciple.domain.DiscipleMode;
import com.cndw.kungfu.model.goods.domain.ModeGoodsInlay;
import com.cndw.kungfu.model.goods.domain.ModeGoodsStarSuit;
import com.cndw.kungfu.model.player.domain.Artifact;
import com.cndw.kungfu.model.player.domain.Dragon;
import com.cndw.kungfu.model.skill.PlayerSkill;
import com.cndw.kungfu.vo.goodsvo.GoodsSuitePropVO;
import com.cndw.kungfu.vo.goodsvo.GoodsSuiteVO;

public class PlayerFormula {

	private static void initFirstProperties(Player player, boolean checkDisciple) {
		Vocation vocation = Context.getCongfigServer().getVocation(player.getVocationId());
		int clacLevel = player.getLevel() - 1;
		int power = 0, physical = 0, agile = 0, wit = 0;
		power = vocation.getPower() + vocation.getAddPower() * clacLevel;
		physical = vocation.getPhysical() + vocation.getAddPhysical() * clacLevel;
		agile = vocation.getAgile() + vocation.getAddAgile() * clacLevel;
		wit = vocation.getWit() + vocation.getAddWit() * clacLevel;
		if (checkDisciple) {
			PlayerMartial playerMartial = Context.getDiscipleServer().getByPlayerId(player.getPlayerId());
			if (playerMartial != null) {
				Collection<Disciple> disciples = playerMartial.getDisciples();
				for (Disciple disciple : disciples) {
					if (disciple.getCampId() <= 0) {
						continue;
					}
					power += disciple.getPower();
					physical += disciple.getPhysical();
					agile += disciple.getAgile();
					wit += disciple.getWit();
				}
			}
		}

		player.setPower(power);
		player.setPhysical(physical);
		player.setAgile(agile);
		player.setWit(wit);

	}

	/**
	 * 只计算基础属性 针对注册后提供的简单方法
	 * 
	 * @param player
	 */
	public static void initProperties(Player player) {

		Vocation vocation = Context.getCongfigServer().getVocation(player.getVocationId());
		int maxHp = 0, maxMp = 0, attack = 0, defense = 0, hit = 0, dodge = 0, crit = 0, tough = 0, speed = 0;
		switch (player.getVocationId()) {
		case 1:
			maxHp = player.getPhysical() * 7;//职业平衡,武者兑换血量增加1点，由6点改为7点。
			maxMp = player.getWit() * 5;
			attack = player.getPower() * 3;
			defense = player.getPhysical() * 3;
			speed = player.getAgile() * 1;
			hit = player.getPower() * 1;
			dodge = player.getAgile() * 1;
			crit = player.getWit() * 1;
			tough = player.getPhysical() * 12 / 10;
			break;
		case 2:
			maxHp = player.getPhysical() * 5;
			maxMp = player.getWit() * 5;
			attack = player.getWit() * 3;
			defense = player.getPhysical() * 3;
			speed = player.getAgile() * 1;
			hit = player.getPower() * 2;
			dodge = player.getAgile() * 1;
			crit = player.getWit() * 1;
			tough = player.getPhysical() * 12 / 10;
			break;
		case 3:
			maxHp = player.getPhysical() * 6;
			maxMp = player.getWit() * 5;
			attack = player.getAgile() * 3;
			defense = player.getPhysical() * 3;
			speed = player.getAgile() * 1;
			hit = player.getPower() * 2;
			dodge = player.getAgile() * 1;
			crit = player.getWit() * 1;
			tough = player.getPhysical() * 12 / 10;
			break;
		default:
			break;
		}

		maxHp += vocation.getHp();
		maxMp += vocation.getMp();

		player.setMaxHp(maxHp);
		player.setMaxMp(maxMp);
		player.setAttack(attack);
		player.setDefense(defense);
		player.setAttackSpeed(speed);
		player.setHit(hit);
		player.setDodge(dodge);
		player.setCrit(crit);
		player.setTough(tough);
	}

	/**
	 * 计算角色属性
	 * 
	 * @param player
	 */
	public static void clacProperties(Player player) {
		initFirstProperties(player, true);// 重置角色1级基础属性
		initProperties(player);

		int maxHp = player.getMaxHp();
		int maxMp = player.getMaxMp();
		int attack = player.getAttack();
		int defense = player.getDefense();
		int hit = player.getHit();
		int dodge = player.getDodge();
		int crit = player.getCrit();
		int tough = player.getTough();
		int speed = player.getAttackSpeed();

		Collection<Goods> equipList = player.getPlayerBoxs().getEquipList();
		/**
		 * 属性的临时变量
		 */
		int eHp = 0, eMp = 0, eAttack = 0, eDefense = 0, eSpeed = 0, eHit = 0, eDodge = 0, eCrit = 0, eTough = 0;
		for (Goods e : equipList) {
			if (e.getGoodsMode() == null) {
				continue;
			}
			eHp += e.getHp();
			eMp += e.getMp();
			eAttack += e.getAttack();
			eDefense += e.getDefense();
			eSpeed += e.getGoodsMode().getSpeed();
			if (e.getGoodsMode().getGoodTypeId() == EquipType.Pendant.goodTypeId()) {//护符收藏功能追加属性
				int percentAdd = player.getDataInfo().intDataGet(ConstantsIntKey.fhfv);
				if (percentAdd > 0 ) {
					eHp += NumberProcesser.percentOnlyAddValue(e.getHp(), percentAdd);
					eMp += NumberProcesser.percentOnlyAddValue(e.getMp(), percentAdd);
					eAttack += NumberProcesser.percentOnlyAddValue(e.getAttack(), percentAdd);
					eDefense += NumberProcesser.percentOnlyAddValue(e.getDefense(), percentAdd);
					//eSpeed += NumberProcesser.percentOnlyAddValue(e.getGoodsMode().getSpeed(), percentAdd);
				}
			}
			// 锻造追加
			int forgeAppend = 0;
			if (e.getForgeLevel() <= 20) {
				forgeAppend = e.getForgeLevel() * e.getGoodsMode().getAppend();
			} else {
				forgeAppend = e.getGoodsMode().getAppend() * 20 + (e.getGoodsMode().getAppend() * (e.getForgeLevel() - 20)) / 2;
			}

			if (e.getAttack() > 0) {
				eAttack += forgeAppend;
			}
			if (e.getHp() > 0) {
				eHp += forgeAppend;
			}
			if (e.getMp() > 0) {
				eMp += forgeAppend;
			}
			if (e.getDefense() > 0) {
				eDefense += forgeAppend;
			}

			// 宝石属性追加
			if (!BlankUtils.isBlank(e.getGemMap())) {
				for (Integer hole : e.getGemMap().keySet()) {
					int id = e.getGemMap().get(hole);
					if (id > 0) {
						ModeGoodsInlay inlay = ModeGoodsInlay.get(id);
						eHp += inlay.getHp();
						eMp += inlay.getMp();
						eAttack += inlay.getAttack();
						eDefense += inlay.getDefense();
						eSpeed += inlay.getSpeed();
					}
				}
			}

			// 追加星级奖励
			int[] append = Context.getGoodsServer().calculateGoodsStar(e.getGoodsMode(), e.getLevel());
			eHit += append[0];
			eDodge += append[1];
			eCrit += append[2];
			eTough += append[3];
		}

		// 星级成套属性追加
		List<ModeGoodsStarSuit> list = ModeGoodsStarSuit.getStarSuite(equipList);
		for (ModeGoodsStarSuit s : list) {
			if (s.isActived()) {
				eHp += s.getHp();
				eMp += s.getMp();
				eAttack += s.getAttack();
				eDefense += s.getDefense();
				eHit += s.getHit();
				eDodge += s.getDodge();
				eCrit += s.getCrit();
				eTough += s.getTough();
			}
		}

		// 附加套装属性
		Map<Integer, GoodsSuiteVO> suiteMap = Context.getGoodsServer().getGoodsSuites(player.getPlayerId());
		for (GoodsSuiteVO suiteVO : suiteMap.values()) {
			for (GoodsSuitePropVO propVO : suiteVO.getProps().values()) {
				if (propVO.isActived()) {
					eHp += propVO.getHp();
					eMp += propVO.getMp();
					eAttack += propVO.getAttack();
					eDefense += propVO.getDefense();
					eHit += propVO.getHit();
					eDodge += propVO.getDodge();
					eCrit += propVO.getCrit();
					eTough += propVO.getTough();
				}
			}
		}

		// 帮派技能
		Map<Integer, Integer> skillMap = player.getDataInfo().getUnionSkillMap();
		if (!BlankUtils.isBlank(skillMap)) {
			for (Map.Entry<Integer, Integer> entry : skillMap.entrySet()) {
				if (entry.getValue() > 0) {
					UnionSkillConfig config = Context.getUnionServer().getUnionSkillConfig(entry.getKey().toString() + entry.getValue().toString());
					if (config == null) {
						continue;
					}
					// 1:加命中,2:加闪避,3:加暴击,4:加韧性,5:加攻击,6:加防御,7:加血,8:加蓝,9:攻速
					switch (config.getType()) {
					case Constants.skillPassiveTypeHit:
						eHit += config.getEffect();
						break;
					case Constants.skillPassiveTypeDodge:
						eDodge += config.getEffect();
						break;
					case Constants.skillPassiveTypeCrit:
						eCrit += config.getEffect();
						break;
					case Constants.skillPassiveTypeTough:
						eTough += config.getEffect();
						break;
					case Constants.skillPassiveTypeAttack:
						eAttack += config.getEffect();
						break;
					case Constants.skillPassiveTypeDefense:
						eDefense += config.getEffect();
						break;
					case Constants.skillPassiveTypeHp:
						eHp += config.getEffect();
						break;
					case Constants.skillPassiveTypeSpeed:
						eSpeed += config.getEffect();
						break;
					}
				}
			}
		}

		int[] ePropertiesAdd = new int[10];
		/**
		 * 增加被动技能的加成
		 */
		PlayerSkill playerSkill = Context.getSkillServer().getPlayerSkill(player.getPlayerId());
		Collection<Skill> skills = playerSkill.getsSkills();
		if (skills != null && skills.size() > 0) {
			for (Skill e : skills) {
				SkillMode skillMode = e.getSkillMode();
				if (skillMode == null) {
					continue;
				}
				if (skillMode.getPassiveType() > 0 && skillMode.getPassiveValue() > 0) {
					int effectValue = skillMode.getPassiveValue();
					int passiveType = skillMode.getPassiveType();
					if (passiveType >= 0 && passiveType <= 9) {
						ePropertiesAdd[passiveType] += effectValue;
					}
				} else if (skillMode.getType() == SkillMode.typeMartial && skillMode.getPassiveAdds() != null) {
					try {
						int[] skillAdd = skillMode.getPassiveAdds();
						eHit += skillAdd[1];
						eDodge += skillAdd[2];
						eCrit += skillAdd[3];
						eTough += skillAdd[4];
						eAttack += skillAdd[5];
						eDefense += skillAdd[6];
						eHp += skillAdd[7];
						eMp += skillAdd[8];
						eSpeed += skillAdd[9];
					} catch (Exception e2) {
						e2.printStackTrace();
					}
				}

			}
		}

		// 丹药加成
		Map<Integer, Integer> drugsAddMap = player.getDataInfo().getDrugsAddMap();
		if (drugsAddMap != null && !drugsAddMap.isEmpty()) {
			for (Map.Entry<Integer, Integer> entry : drugsAddMap.entrySet()) {
				if (entry.getKey() >= 0 && entry.getKey() <= 9) {
					ePropertiesAdd[entry.getKey()] += entry.getValue();
				}
			}
		}

		int titleId = player.getTitleId();// 称号加成
		if (titleId > 0) {
			Title title = Context.getCacheCenter().getTitle(titleId);
			if (title != null) {
				int tAdd[] = title.getAttris();
				eHit += tAdd[1];
				eDodge += tAdd[2];
				eCrit += tAdd[3];
				eTough += tAdd[4];
				eAttack += tAdd[5];
				eDefense += tAdd[6];
				eHp += tAdd[7];
				eMp += tAdd[8];
				eSpeed += tAdd[9];
			}
		}
		// vip加成
		if (player.stateContains(Constants.playerState32_vipAdd) && player.getKnightTrueLevel() > 1) {
			eHp += ConstantsModel.vipAdd[player.getKnightLevel()][0];
			eAttack += ConstantsModel.vipAdd[player.getKnightLevel()][1];
			eDefense += ConstantsModel.vipAdd[player.getKnightLevel()][2];
		}
		// 神器加成
		Artifact artifact = player.getDataInfo().getArtifact();
		if (artifact != null) {
			int[] aftAdd = artifact.getAttris();
			eHit += aftAdd[1];
			eDodge += aftAdd[2];
			eCrit += aftAdd[3];
			eTough += aftAdd[4];
			eAttack += aftAdd[5];
			eDefense += aftAdd[6];
			eHp += aftAdd[7];
			eMp += aftAdd[8];
			eSpeed += aftAdd[9];
		}
		//龙纹加成
		int lw = player.getDataInfo().intDataGet(ConstantsIntKey.lw);
		if (lw > 0) {
			Dragon dragon = Dragon.getOne(lw);
			if (dragon!=null) {
				try {
					eAttack += dragon.getAddsVar()[0];
					eDefense += dragon.getAddsVar()[1];
					eHp += dragon.getAddsVar()[2];
					eSpeed += dragon.getAddsVar()[3];
				} catch (Exception e) {
					e.printStackTrace();
				}
				
			}
		}
		//结婚加成
		int xl = player.getDataInfo().intDataGet(ConstantsIntKey.xl);
		if (xl > 0 ) {
			int[] aftAdd = FormulaMarry.getAddv(xl);
			if (aftAdd != null) {
				eHit += aftAdd[1];
				eDodge += aftAdd[2];
				eCrit += aftAdd[3];
				eTough += aftAdd[4];
				eAttack += aftAdd[5];
				eDefense += aftAdd[6];
				eHp += aftAdd[7];
				eMp += aftAdd[8];
				eSpeed += aftAdd[9];
			}
		}

		eHit += ePropertiesAdd[1];
		eDodge += ePropertiesAdd[2];
		eCrit += ePropertiesAdd[3];
		eTough += ePropertiesAdd[4];
		eAttack += ePropertiesAdd[5];
		eDefense += ePropertiesAdd[6];
		eHp += ePropertiesAdd[7];
		eMp += ePropertiesAdd[8];
		eSpeed += ePropertiesAdd[9];

		maxHp += eHp;
		maxMp += eMp;
		attack += eAttack;
		defense += eDefense;
		hit += eHit;
		dodge += eDodge;
		crit += eCrit;
		tough += eTough;
		speed += eSpeed;

		player.setMaxHp(maxHp);
		player.setMaxMp(maxMp);
		player.setAttack(attack);
		player.setDefense(defense);
		player.setAttackSpeed(speed);
		player.setHit(hit);
		player.setDodge(dodge);
		player.setCrit(crit);
		player.setTough(tough);

		clacOtherProperties(player);
		clacAddition(player);

	}

	/**
	 * 计算门派的加成数据
	 * 
	 * @param player
	 */
	private static void clacOtherProperties(Player player) {

		/**
		 * 属性的临时变量
		 */
		int eHp = 0, eMp = 0, eAttack = 0, eDefense = 0, eHit = 0, eDodge = 0, eCrit = 0, eTough = 0;
		int eSpeed = 0;

		PlayerMartial playerMartial = Context.getDiscipleServer().getByPlayerId(player.getPlayerId());
		if (playerMartial != null) {

			int[] dowerClacArr = new int[15];

			for (Disciple d : playerMartial.getDisciples()) {
				if (d.getCampId() <= 0) {
					continue;
				}
				DiscipleMode mode = d.getDiscipleMode();
				if (mode == null) {
					continue;
				}
				FormulaDisciple.clacOneDisciple(d, dowerClacArr);
			}

			eHit += dowerClacArr[1];
			eDodge += dowerClacArr[2];
			eCrit += dowerClacArr[3];
			eTough += dowerClacArr[4];
			eAttack += dowerClacArr[5];
			eDefense += dowerClacArr[6];
			eHp += dowerClacArr[7];
			eMp += dowerClacArr[8];
			eSpeed += dowerClacArr[9];

			player.setHurtAdd(dowerClacArr[10]);
			player.setHurtRemove(dowerClacArr[11]);
			player.setHurtReflex(dowerClacArr[12]);
			player.setHurtAbsorb(dowerClacArr[13]);
			player.setCritAdd(dowerClacArr[14]);

		}

		player.setMaxHp(player.getMaxHp() + eHp);
		player.setMaxMp(player.getMaxMp() + eMp);
		player.setAttack(player.getAttack() + eAttack);
		player.setDefense(player.getDefense() + eDefense);

		player.setHit(player.getHit() + eHit);
		player.setDodge(player.getDodge() + eDodge);
		player.setCrit(player.getCrit() + eCrit);
		player.setTough(player.getTough() + eTough);

		player.setAttackSpeed(player.getAttackSpeed() + eSpeed);

	}

	private static void clacAddition(Player player) {
		int maxHp = player.getMaxHp();
		int maxMp = player.getMaxMp();
		int attack = player.getAttack();
		int defense = player.getDefense();
		int hit = player.getHit();
		int dodge = player.getDodge();
		int crit = player.getCrit();
		int tough = player.getTough();
		/**
		 * 属性的临时变量
		 */
		int eHp = 0, eMp = 0, eAttack = 0, eDefense = 0, eHit = 0, eDodge = 0, eCrit = 0, eTough = 0;

		// if (player.getVip() != null) {
		// eAttack += NumberProcesser.percentOnlyAddValue(attack,
		// player.getVip().getPlayerAttackR());
		// eDefense += NumberProcesser.percentOnlyAddValue(defense,
		// player.getVip().getPlayerDefenseR());
		//
		// eHit += NumberProcesser.percentOnlyAddValue(hit,
		// player.getVip().getPlayerHitR());
		// eDodge += NumberProcesser.percentOnlyAddValue(dodge,
		// player.getVip().getPlayerDodgeR());
		// eHp += NumberProcesser.percentOnlyAddValue(maxHp,
		// player.getVip().getPlayerHpR());
		//
		// if (player.getVip().getPlayerSpeedR() > 0) {
		// player.setAttackSpeed(NumberProcesser.percentClac(player.getAttackSpeed(),
		// player.getVip().getPlayerSpeedR()));
		// }
		//
		// }
		maxHp += eHp;
		maxMp += eMp;
		attack += eAttack;
		defense += eDefense;
		hit += eHit;
		dodge += eDodge;
		crit += eCrit;
		tough += eTough;

		player.setMaxHp(maxHp);
		player.setMaxMp(maxMp);
		player.setAttack(attack);
		player.setDefense(defense);
		player.setHit(hit);
		player.setDodge(dodge);
		player.setCrit(crit);
		player.setTough(tough);

		if (player.getHp() > maxHp) {
			player.setHp(maxHp);
		}
		if (player.getMp() > maxMp) {
			player.setMp(maxMp);
		}
	}

	public static void clacScore(Player player) {
		if (player.getPlayerId() == 0) {
			clacScorePlayer(player);
			return;
		}
		try {
			int score = FormulaScore.calcAllScore(player)[0][0];
			player.setScore(score);
		} catch (Exception e) {
			e.printStackTrace();
			// 内功（角色评分）
			clacScorePlayer(player);

		}

	}

	public static void clacScorePlayer(Player player) {
		int score = player.getMaxHp() / 10 + (player.getAttack() + player.getDefense()) / 3
				+ (player.getHit() + player.getDodge() + player.getCrit() + player.getTough() + player.getAttackSpeed()) / 2 + player.getHurtAdd()
				+ player.getHurtAbsorb() + player.getHurtReflex() + player.getHurtRemove() + player.getCritAdd();
		score = score / 10;
		player.setScore(score);
	}

}
